home *** CD-ROM | disk | FTP | other *** search
/ Mac Mania 4 / MacMania 4.toast / / Demo's / Igor Demo Pro / 1 PutContentsIn Igor Pro Folder / WaveMetrics Procedures / Image and Contour Plots / Path Profile < prev   
Text File  |  1996-01-30  |  11KB  |  456 lines

  1. #pragma rtglobals=1
  2.  
  3. #include <Strings as Lists>
  4.  
  5. | NOTE: This procedure file requires that the MDInterpolator XOP be installed
  6. |        in the Igor Extensions folder.
  7. |
  8. |  For a demonstration experiment showing how this procedure file is used,
  9. |  see the experiment file "Path Profile Demo" in the Graphs subfolder of the
  10. |  Examples folder in your Igor Pro folder.
  11. |
  12. |  These procedures are written to be used with the control panel that is made by
  13. |  the procedure file.  The functions that do the actual work could be used by themselves
  14. |  if you did some work to modify them, or to set up the data folders and global variables
  15. |  that the procedures need.
  16. |
  17. |  Possible Improvements:
  18. |    Make it work with Images and Contour Plots that aren't displayed on Left and Bottom axes.
  19.  
  20. Menu "Macros"
  21.     "Profile Control Panel", MakeProfilePanel()
  22. end
  23.  
  24. Proc MakeProfilePanel()
  25.  
  26.     Silent 1
  27.  
  28.     String SaveFolder=GetDataFolder(1)
  29.     SetDataFolder root:
  30.  
  31.     | Test for private data folder for these procedures, make it if it doesn't exist
  32.     
  33.     if (DataFolderExists("root:Packages")==0)
  34.         NewDataFolder/S Packages
  35.         NewDataFolder/S WMProfileProc
  36.     else
  37.         SetDataFolder Packages
  38.         if (DataFolderExists("WMProfileProc")==0)
  39.             NewDataFolder/S WMProfileProc
  40.         else
  41.             SetDataFolder WMProfileProc
  42.         endif
  43.     endif
  44.     
  45.     |  Some globals used by these procedures
  46.     
  47.     Variable/G PR_NumProfPoints=100
  48.     String/G PR_PathXName="PathXWave"
  49.     String/G PR_PathYName="PathYWave"
  50.     String/G PR_OutWaveName="ProfileWave"
  51.     SetDataFolder $SaveFolder
  52.  
  53.     if (wintype("ProfilePanel") == 7)
  54.         DoWindow/F ProfilePanel
  55.     else
  56.         ProfilePanel()
  57.     endif
  58. end
  59.  
  60. | The function that actually calculates the profile data
  61.  
  62. Function InterpPath(Wave2D, PathY, PathX, NumOutPnts, OutName, AtPoints)
  63.     Wave Wave2D, PathY, PathX
  64.     Variable NumOutPnts
  65.     String OutName
  66.     Variable AtPoints
  67.     
  68. |    String OutName=UniqueName(NameofWave(Wave2D)+"_path", 1, 0)
  69. |    print "Wave containing path is ", OutName
  70.     
  71.     Variable TotalLength,LengthInc, LengthP, PointX, PointY,Distance
  72.     Variable/C Point
  73.     Variable ind, endloop
  74.     Variable XVal, YVal
  75.     Variable hasX=waveExists(PathX)
  76.     
  77. |    print "InterpPath: hasX = ", hasX
  78.     
  79.     if (AtPoints)
  80.         NumOutPnts = numpnts(PathY)
  81.     endif
  82.     Make/O/N=(NumOutPnts) $OutName
  83.     Wave w=$OutName
  84.     Duplicate/O PathY, root:Packages:WMProfileProc:PR_LineLength
  85.     Wave PR_LineLength=root:Packages:WMProfileProc:PR_LineLength
  86.     
  87.     if (AtPoints)
  88.         ind = 0
  89.         endloop=NumOutPnts
  90.         do
  91.             if (hasX)
  92.                 XVal = PathX[ind]
  93.             else
  94.                 XVal = pnt2x(pathY, ind)
  95.             endif
  96.             // interp2d is in the MDInterpolator XOP.
  97.             // If you get an error here, put an alias to MDInterpolator in Igor Extensions and relaunch Igor.
  98.             w[ind] = interp2d(wave2D, XVal, pathY[ind])
  99.             ind += 1
  100.         while(ind<endloop)
  101.     else
  102.         TotalLength=WaveLineLengthXY(PathX, PathY, PR_LineLength)
  103. |        print "TotalLength",TotalLength
  104.         LengthInc = TotalLength/(NumOutPnts-1)
  105.         SetScale/I x 0,TotalLength,$OutName
  106.  
  107.         ind=0
  108.         endloop=NumOutPnts
  109.         do
  110.             Distance=ind*LengthInc
  111. |            print "ProfileProc: distance = ", distance
  112.             Point=XYatDistance(PR_LineLength, PathX, PathY, Distance)
  113. |            print "ProfileProc: point, ind:",point, ind
  114.             w[ind] = interp2d(Wave2D, real(Point), imag(Point))
  115. |            print point, ind, w[ind]
  116.         
  117.             ind += 1
  118.         while(ind< endloop)
  119.     endif
  120.     
  121.     KillWaves PR_LineLength
  122. end
  123.  
  124. | XYatDistance calculates the X, Y points corresponding to a distance along the wave, or pair of waves.
  125. |  If XWave doesn't exist, does a waveform calculation, if it does exist, does XY calculation.
  126. |
  127. |  Requires that WaveLineLengthXY be run first to calculate the line length wave.
  128.  
  129. Function/C XYatDistance(LengthWave, XWave, YWave, Distance)
  130.     Wave LengthWave, XWave, YWave
  131.     Variable/D Distance
  132.     
  133.     Variable hasX = waveExists(XWave)
  134.     
  135. |    print "XYatDistance: hasX = ", hasX
  136.     
  137.     Variable i=0, PNum, TP=numpnts(LengthWave), Px, Py
  138.     Variable XVal0, XVal1
  139.     
  140.     do
  141. |        print "XYatDistance, d, LW[i]:",Distance, LengthWave[i]
  142.         if (Distance < LengthWave[i])
  143.             PNum=i-1
  144.             break
  145.         endif
  146.             
  147.         i += 1
  148.     while (i < TP)
  149.     
  150.     if (i > TP)
  151. |        print "XYatDistance: i > TP"
  152.         return(cmplx(NaN, NaN))
  153.     endif
  154.     
  155.     Distance -= LengthWave[PNum]
  156.     Distance = Distance/(LengthWave[PNum+1]-LengthWave[PNum])
  157.     
  158.     if (hasX)
  159.         Xval0 = XWave[PNum]
  160.         Xval1 = XWave[PNum+1]
  161.     else
  162.         Xval0 = pnt2x(YWave, PNum)
  163.         Xval1 = pnt2x(YWave, PNum+1)
  164.     endif
  165.  
  166.     Px = Xval0 + Distance*(Xval1-Xval0)
  167.     Py = YWave[PNum] + Distance*(YWave[PNum+1]-YWave[PNum])
  168.     
  169.     return cmplx(Px, Py)
  170. end
  171.  
  172. | WaveLineLengthXY calculates a new wave with line length along the wave or wave pair.
  173. | Each element in the calculated wave is the total length of the given wave(s) up to the
  174. | corresponding element.
  175.  
  176. Function/D WaveLineLengthXY(InWaveX, InWaveY, LengthWave)
  177.     Wave InWaveX, InWaveY, LengthWave
  178.     
  179.     Variable hasX=waveExists(InWaveX)
  180.     Variable Xval0, Xval1
  181.     
  182. |    print "WaveLineLengthXY: hasX = ", hasX
  183.     
  184.     if (hasX)
  185.         if (numpnts(InWaveX) != numpnts(InWaveY))
  186. |            print "WaveLineLengthXY: wrong X points"
  187.             return NaN
  188.         endif
  189.     endif
  190.     
  191.     if (numpnts(InWaveY) != numpnts(LengthWave))
  192. |        print "WaveLineLengthXY: wrong LengthWave"
  193.         return NaN
  194.     endif
  195.     
  196.     Variable/D Sum=0
  197.     Variable i=0, numiters=numpnts(InWaveY)-1
  198.     
  199.     LengthWave[0] = 0
  200.     do
  201.         if (hasX)
  202.             Xval0 = InWaveX[i]
  203.             Xval1 = InWaveX[i+1]
  204.         else
  205.             Xval0 = pnt2x(InWaveY, i)
  206.             Xval1 = pnt2x(InWaveY, i+1)
  207.         endif
  208.  
  209.         sum += sqrt((Xval1-Xval0)^2 + (InWaveY[i+1]-InWaveY[i])^2)
  210.         LengthWave[i+1] = sum
  211.     
  212.         i += 1
  213.     while (i<numiters)
  214.     
  215.     return sum
  216. end
  217.  
  218.  
  219. | ListContoursImages() returns a string containing the names of both images and
  220. | contour plots.  Eliminates duplicate names.
  221.  
  222. Function/S ListContoursImages()
  223.  
  224.     String ContourList=ContourNameList("",";")
  225.     String ImageList=ImageNameList("",";")
  226.     String Name1, Name2
  227.     Variable i1=0, i2, Match
  228.     
  229.     i1 = 0
  230.     do
  231.         Name1=GetStrFromList(ImageList, i1, ";")
  232.         if (strlen(Name1) == 0)
  233.             break
  234.         endif
  235.         i2 = 0
  236.         do
  237.             Name2 = GetStrFromList(ContourList, i2, ";")
  238.             if (strlen(Name2) == 0)
  239.                 break
  240.             endif
  241.             if (cmpstr(Name1, Name2) == 0)
  242.                 Match = 1
  243.                 break
  244.             else
  245.                 Match = 0
  246.             endif
  247.             i2 += 1
  248.         while(1)
  249.         if (Match == 0)
  250.             ContourList += Name1+";"
  251.         endif
  252.         i1 += 1
  253.     while (1)
  254.     
  255.     return ContourList
  256. end
  257.  
  258. |***************************
  259. | Action procedures for controls follow
  260. |***************************
  261.  
  262. Function MakePathProc(ctrlName) : ButtonControl
  263.     String ctrlName
  264.     
  265.     SVAR PathXName=root:Packages:WMProfileProc:PR_PathXName
  266.     SVAR PathYName=root:Packages:WMProfileProc:PR_PathYName
  267. |    NVAR HasPathXWave=root:Packages:WMProfileProc:HasPathXWave
  268.  
  269.     Variable hasX
  270.     
  271. |    print "X,Y:", PathXName, PathYName
  272.     
  273.     if (strlen(PathYName) == 0)
  274.         Abort "No name for Y path wave"
  275.     endif
  276.     if (strlen(PathXName) == 0)
  277.         Abort "No name for X path wave"
  278.     endif
  279.     
  280.     Make/O/N=2 $PathXName
  281.     wave PR_XWave=$PathXName
  282.     Make/O/N=2 $PathYName
  283.     wave PR_YWave=$PathYName
  284.     
  285.     
  286.     GetAxis bottom
  287.     
  288. |    print V_min, V_max
  289.     PR_XWave[0] = V_min
  290.     PR_XWave[1] = V_max
  291.     
  292.     GetAxis left
  293. |    print V_min, V_max
  294.     PR_YWave[0] = V_min
  295.     PR_YWave[1] = V_max
  296.     
  297.     AppendToGraph $PathYName vs $PathXName
  298.     ControlUpdate PathWavePopup
  299.     String traceList=traceNameList("", ";",1)
  300. |    print traceList
  301.  
  302.     String currentName
  303.     Variable i=0
  304.     do
  305.         currentName=GetStrFromList(traceList, i,";")
  306. |        print currentName
  307.         if (strlen(currentName)== 0)
  308.             break
  309.         endif
  310.         if (cmpstr(currentName, PathYName) == 0)
  311.             PopupMenu PathWavePopup,mode=i+1
  312.             break
  313.         endif
  314.     
  315.         i += 1
  316.     while (1)
  317.     
  318. End
  319.  
  320. Function EditPathProc(ctrlName) : ButtonControl
  321.     String ctrlName
  322.     
  323.     String TraceName
  324.         
  325.         ControlInfo PathWavePopup
  326.         TraceName=S_value
  327.     
  328.     Wave PathY = TraceNameToWaveRef("", TraceName)
  329. |    print "PathY = ", NameofWave(PathY)
  330.     Wave PathX = XWaveRefFromTrace("", TraceName)
  331. |    print "PathX = ", NameofWave(PathX)
  332.  
  333.     if (WaveExists(PathY) == 0)
  334.         Abort "Path Y wave doesn't exist"
  335.     endif
  336.     if (WaveExists(PathX) == 0)
  337.         Abort "Please do not edit Waveform traces, only XY traces"
  338.     endif
  339.  
  340.     
  341.     String Window=WinName(0,1)
  342.     
  343.     DoWindow/F $Window
  344.     ShowTools
  345.     
  346. |    print "Print from pathWaves:", PathY[0], PathX[0]
  347.     GraphWaveEdit $TraceName
  348.     
  349. End
  350.  
  351. Function ProfileProc(ctrlName) : ButtonControl
  352.     String ctrlName
  353.     
  354.     SVAR PR_OutWaveName=root:Packages:WMProfileProc:PR_OutWaveName
  355.     
  356.     NVAR PR_NumProfPoints=root:Packages:WMProfileProc:PR_NumProfPoints
  357.     
  358.     String ContourList=ContourNameList("",";")
  359.     String ContourName, PathName
  360.     Variable AtPoints
  361.     
  362.     ContourName=GetStrFromList(ContourList, 0, ";")
  363.     if (strlen(ContourName) == 0)
  364.         ContourList = ImageNameList("",";")
  365.         ContourName = GetStrFromList(ContourList, 0, ";")
  366.         if (strlen(ContourName) == 0)
  367.             abort "No contour plot or image found in the top graph window"
  368.         else
  369.             Wave Wave2d=ImageNameToWaveRef("", ContourName)
  370.         endif
  371.     else
  372.     |    print "ContourName = ", ContourName
  373.         Wave Wave2d=ContourNameToWaveRef("", ContourName)
  374.     endif
  375.         
  376.         ControlInfo PathWavePopup
  377.         PathName = S_value
  378.     
  379.     Wave PathY = TraceNameToWaveRef("",PathName)
  380.     Wave PathX = XWaveRefFromTrace("",PathName)
  381.     
  382.     ControlInfo AtPointsCheck
  383.     AtPoints=V_value
  384.  
  385.     InterpPath(Wave2D, PathY, PathX, PR_NumProfPoints, PR_OutWaveName, AtPoints)
  386.     
  387. End
  388.  
  389.  
  390.  
  391.  
  392. Function ProfileGraphProc(ctrlName) : ButtonControl
  393.     String ctrlName
  394.     
  395.     SVAR PR_OutWaveName=root:Packages:WMProfileProc:PR_OutWaveName
  396.     
  397.     Display $PR_OutWaveName
  398.  
  399. End
  400.  
  401.  
  402. Function InterpCheckProc(ctrlName,checked) : CheckBoxControl
  403.     String ctrlName
  404.     Variable checked
  405.     
  406.     if (checked)
  407.         Checkbox AtPointsCheck, value=0
  408.     else
  409.         Checkbox AtPointsCheck, value=1
  410.     endif
  411.  
  412. End
  413.  
  414. Function ProfileCheckProc(ctrlName,checked) : CheckBoxControl
  415.     String ctrlName
  416.     Variable checked
  417.     Variable CtrlProfChk, CtrlInterpChk
  418.     
  419.     if (checked)
  420.         Checkbox InterpPathCheck, value=0
  421.     else
  422.         Checkbox InterpPathCheck, value=1
  423.     endif
  424.  
  425.  
  426. End
  427.  
  428. |*******************************
  429. | Recreation macro for profile control panel
  430. |*******************************
  431.  
  432. Proc ProfilePanel()
  433.     PauseUpdate; Silent 1        | building window...
  434.     NewPanel /W=(273,41,541,334)
  435.     SetDrawLayer UserBack
  436.     DrawRect 36,33,228,106
  437.     DrawRect 23,142,245,188
  438.     SetVariable SetXPathWave,pos={48,38},size={169,17},title="X Path Name:"
  439.     SetVariable SetXPathWave,limits={-INF,INF,1},value= root:Packages:WMProfileProc:PR_PathXName
  440.     SetVariable SetYPathWave,pos={48,57},size={169,17},title="Y Path Name:"
  441.     SetVariable SetYPathWave,limits={-INF,INF,1},value= root:Packages:WMProfileProc:PR_PathYName
  442.     Button MakePathButton,pos={90,81},size={83,20},proc=MakePathProc,title="Make Path"
  443.     Button EditPathButton,pos={91,110},size={83,20},proc=EditPathProc,title="Edit Path"
  444.     Button ProfileButton,pos={44,250},size={83,20},proc=ProfileProc,title="Do Profile"
  445.     Button ProfileGraphButton,pos={137,250},size={83,20},proc=ProfileGraphProc,title="Graph"
  446.     SetVariable setvar0,pos={28,195},size={216,17},title="Number of Points"
  447.     SetVariable setvar0,limits={0,INF,1},value= root:Packages:WMProfileProc:PR_NumProfPoints
  448.     SetVariable SetOutWaveName,pos={28,230},size={217,17},title="Output Wave Name"
  449.     SetVariable SetOutWaveName,limits={-INF,INF,1},value= root:Packages:WMProfileProc:PR_OutWaveName
  450.     PopupMenu PathWavePopup,pos={51,6},size={149,19},title="Path trace:"
  451.     PopupMenu PathWavePopup,mode=6,value= #"TraceNameList(\"\",\";\",1)"
  452.     CheckBox InterpPathCheck,pos={29,144},size={177,20},proc=InterpCheckProc,title="Interpolate along path",value=1
  453.     CheckBox AtPointsCheck,pos={29,163},size={202,20},proc=ProfileCheckProc,title="Profile at path wave points",value=0
  454. EndMacro
  455.  
  456.